< previous page page_246 next page >

Page 246
0246-01.gif
Figure S27-2:
NT Performance Monitor illustrates a memory leak
receives the LPOLESTR * pointerthe address of an LPOLESTR variable that contains the address of the string data. This means that the function can modify the LPOLESTR variable. In fact, if you look at the description of this parameter, you'll see
LPOLESTR * ppsz //Indirect pointer to the resulting string on return
This means that the LPOLESTR parameter that is referenced when the function is called is loaded by the function with a pointer to the string data.
In the original puzzle code, the StringFromCLSID does load the MyString variable with a pointer to a NULL-terminated Unicode string. But the function nevertheless fails in two ways. First, the length that precedes every BSTR is not set by this function (because it is not a BSTR). Next, the pointer is not allocated by the OLE subsystem. Under Windows NT, as soon as Visual Basic attempts to treat the pointer as a BSTR, an exception occurs. Under Windows 95, no exception occursat least, not right awaybut the string length is incorrect, and the previous string referenced by the variable is "lost" because the pointer was overwritten.
Since Visual Basic does not provide any automatic way to handle the LPOLESTR * parameter type, it's up to you to create a declaration that gives the API function the information it wants. In this case, the function needs to see a pointer to a 32-bit variable that it can load with a pointer to a string.
The easiest way to pass a pointer to a 32-bit variable is to pass a Long variable by reference, leading to the following declaration:
Private Declare Function StringFromCLSID Lib "ole32.dll" _
(lpclsid As CLSID, lp0lestr As Long) As Long
Now all you need to do is figure out a way to retrieve the string data from the Long variable.
You might want to take a few minutes (or hours) to tackle this yourself before reading farther.

 
< previous page page_246 next page >